# frozen_string_literal: true

require 'spec_helper'

RSpec.describe GitlabSchema.types['VulnerabilityResponse'] do
  let_it_be(:project) { create(:project) }
  let_it_be(:user) { create(:user) }
  let_it_be(:pipeline) { create(:ee_ci_pipeline, :with_api_fuzzing_report, project: project) }

  before do
    stub_licensed_features(api_fuzzing: true, security_dashboard: true)

    project.add_developer(user)
  end

  let(:fields) do
    %i[body status_code reason_phrase headers]
  end

  subject { GitlabSchema.execute(query, context: { current_user: user }).as_json }

  specify { expect(described_class.graphql_name).to eq('VulnerabilityResponse') }

  it { expect(described_class).to have_graphql_fields(fields) }

  describe 'checking field contents' do
    before do
      vulnerabilities = subject.dig('data', 'project', 'pipeline', 'securityReportFindings', 'nodes')
      @vulnerability = vulnerabilities.find { |v| v['title'] == "CORS misconfiguration at 'http://127.0.0.1:7777/api/users'" }
    end

    context 'evidence.response fields' do
      let(:query) do
        %(
        query {
          project(fullPath: "#{project.full_path}") {
            pipeline(iid: "#{pipeline.iid}") {
              securityReportFindings {
                nodes {
                  title
                  evidence {
                    response {
                      body
                      statusCode
                      reasonPhrase
                      headers {
                        name
                        value
                      }
                    }
                  }
                }
              }
            }
          }
        }
      )
      end

      it 'checks the contents of the fields' do
        response = @vulnerability['evidence']['response']

        expect(response['reasonPhrase']).to eq('OK')
        expect(response['statusCode']).to eq(200)
        expect(response['body']).to eq('[{"user_id":1,"user":"admin","first":"Joe","last":"Smith","password":"Password!"}]')
        expect(response['headers'].first).to eq({ 'name' => 'Server', 'value' => 'TwistedWeb/20.3.0' })
      end
    end

    context 'evidence.supportingMessages[].response fields' do
      let(:query) do
        %(
        query {
          project(fullPath: "#{project.full_path}") {
            pipeline(iid: "#{pipeline.iid}") {
              securityReportFindings {
                nodes {
                  title
                  evidence {
                    supportingMessages {
                      name
                      response {
                        body
                        statusCode
                        reasonPhrase
                        headers {
                          name
                          value
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      )
      end

      it 'checks the contents of the fields' do
        response = @vulnerability['evidence']['supportingMessages'].find { |m| m['name'] == 'Recorded' }['response']

        expect(response['reasonPhrase']).to eq('OK')
        expect(response['statusCode']).to eq(200)
        expect(response['body']).to eq('[{"user_id":1,"user":"admin","first":"Joe","last":"Smith","password":"Password!"}]')
        expect(response['headers'].first).to eq({
                                                  "name" => "Server",
                                                  "value" => "TwistedWeb/20.3.0"
                                                })
      end
    end
  end
end
